package com.wmh.baseservice.operationaid.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.mybatisplus.enums.SortMode;
import com.wmh.baseservice.common.mybatisplus.structure.LambdaQueryWrapperX;
import com.wmh.baseservice.operationaid.enums.ContrastRelation;
import com.wmh.baseservice.operationaid.enums.ContrastUnit;
import com.wmh.baseservice.operationaid.mapper.TbStoreDataMapper;
import com.wmh.baseservice.operationaid.entity.TbStoreData;
import com.wmh.baseservice.operationaid.pojo.vo.store.*;
import com.wmh.baseservice.operationaid.service.TbStoreDataService;
import com.wmh.baseservice.operationaid.utils.CalculateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @author 谢骏
 * @description 针对表【operation_aid_tb_store_data(运营助手-淘宝店铺数据)】的数据库操作Service实现
 * @createDate 2023-06-30 15:50:52
 */
@Service
@Slf4j
public class TbStoreDataServiceImpl extends ServiceImpl<TbStoreDataMapper, TbStoreData>
        implements TbStoreDataService {

    @Resource
    private TbStoreDataMapper tbStoreDataMapper;

    @Override
    public void commit(TbStoreCommitDataReqVO reqVO) {
        TbStoreData entity = baseMapper.selectOne(new LambdaQueryWrapperX<TbStoreData>()
                .eq(TbStoreData::getDataDate, reqVO.getDataDate())
                .eq(TbStoreData::getStoreName, reqVO.getStoreName()));
        // 更新
        if (!Objects.isNull(entity)) {
            BeanUtils.copyProperties(reqVO, entity);
            // 新增
        } else {
            entity = new TbStoreData();
            BeanUtils.copyProperties(reqVO, entity);
            entity.setDataDate(LocalDateTimeUtil.parse(reqVO.getDataDate() + "T00:00:00"));
        }
        saveOrUpdate(entity);
    }

    @Override
    public void batchRemove(List<String> ids) {
        remove(new LambdaQueryWrapperX<TbStoreData>()
                .in(TbStoreData::getId, ids));
    }

    @Override
    public TbStoreOneDayComparisonRespVO oneDayComparison(TbStoreOneDayComparisonReqVO reqVO) {
        TbStoreData data1 = baseMapper.selectOne(new LambdaQueryWrapperX<TbStoreData>()
                .eq(TbStoreData::getStoreName, reqVO.getStoreName())
                .eq(TbStoreData::getDataDate, LocalDateTimeUtil.parse(reqVO.getDate1() + "T00:00:00"))
        );
        TbStoreData data2 = baseMapper.selectOne(new LambdaQueryWrapperX<TbStoreData>()
                .eq(TbStoreData::getStoreName, reqVO.getStoreName())
                .eq(TbStoreData::getDataDate, LocalDateTimeUtil.parse(reqVO.getDate2() + "T00:00:00"))
        );
        if (ObjectUtil.isNull(data1) || ObjectUtil.isNull(data2)) {
            throw new ServiceException("未获取到相关数据");
        }
        TbStoreExponentField leftData = new TbStoreExponentField();
        TbStoreExponentField rightData = new TbStoreExponentField();
        BeanUtils.copyProperties(data1, leftData);
        BeanUtils.copyProperties(data2, rightData);
        List<TbStoreOneDayComparisonRespVO.Diff> diffs = CalculateUtils.calObjectNumberFieldDiffPer(leftData, rightData, TbStoreOneDayComparisonRespVO.Diff.class);
        return new TbStoreOneDayComparisonRespVO().setLeftData(leftData).setRightData(rightData)
                .setDiffValue(diffs.get(0)).setDiffPercentage(diffs.get(1));
    }

    @Override
    public TbStoreSameDateComparisonRespVO sameDateComparison(TbStoreSameDateComparisonReqVO reqVO) {
        log.info("sameDateComparison : {}", reqVO);
        LocalDateTime[] dateScope = initSameDateComparisonDateScope(reqVO);
        List<TbStoreData> list = baseMapper.selectList(new LambdaQueryWrapperX<TbStoreData>()
                .eq(TbStoreData::getStoreName, reqVO.getStoreName())
                .between(TbStoreData::getDataDate, dateScope[0], dateScope[1])
                .orderByDesc(TbStoreData::getDataDate)
        );
        return TbStoreSameDateComparisonRespVO.builder(list, LocalDateTimeUtil.parse(reqVO.getStartDate() + "T00:00:00"),
                LocalDateTimeUtil.parse(reqVO.getEndDate() + "T00:00:00"),reqVO.getUnit(), reqVO.getRelation());
    }

    private LocalDateTime[] initSameDateComparisonDateScope(TbStoreSameDateComparisonReqVO reqVO) {
        LocalDateTime start = LocalDateTimeUtil.parse(reqVO.getStartDate() + "T00:00:00");
        LocalDateTime end = LocalDateTimeUtil.parse(reqVO.getEndDate() + "T00:00:00");
        if (ContrastRelation.TQ.equals(reqVO.getRelation())) {
            if (ContrastUnit.DAY.equals(reqVO.getUnit())) {
                start = start.minusDays(7);
            }
        }else if(ContrastRelation.LQ.equals(reqVO.getRelation())){
            if (ContrastUnit.DAY.equals(reqVO.getUnit())){
                start = start.minusDays(1);
            }else if(ContrastUnit.WEEK.equals(reqVO.getUnit())){
                start = start.minusDays(7);
            }
        }
        return new LocalDateTime[]{start, end};
    }

    @Override
    public List<String> getStoreOptions() {
        return tbStoreDataMapper.getStoreOptions();
    }

    @Override
    public List<LocalDateTime> getDataDateOptions() {
        return tbStoreDataMapper.getDataDateOptions();
    }

    @Override
    public List<TbStoreData> getList(TbStoreListReqVO reqVO) {
        LambdaQueryWrapperX<TbStoreData> wrapper = new LambdaQueryWrapperX<TbStoreData>()
                .eq(StrUtil.isNotBlank(reqVO.getStoreName()), TbStoreData::getStoreName, reqVO.getStoreName());
        if (StrUtil.isAllNotBlank(reqVO.getStartDate(), reqVO.getEndDate())) {
            wrapper.between(TbStoreData::getDataDate,
                    LocalDateTimeUtil.parse(reqVO.getStartDate() + "T00:00:00"),
                    LocalDateTimeUtil.parse(reqVO.getEndDate() + "T00:00:00"));
        }
        if (StrUtil.isNotBlank(reqVO.getSortField()) && reqVO.getSortField().equals(TbStoreData.COL_DATA_DATE)) {
            if (SortMode.DESC.isASC(reqVO.getSortMode())) {
                wrapper.orderByDesc(TbStoreData::getDataDate);
            } else {
                wrapper.orderByAsc(TbStoreData::getDataDate);
            }
        }
        return tbStoreDataMapper.selectList(wrapper);
    }
}




